# _*_ coding:utf-8 _*_
import os.path
import time

from selenium.common.exceptions import TimeoutException, NoAlertPresentException, InvalidSwitchToTargetException
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from utils.Logging_tools.log_control import INFO,ERROR
from selenium.webdriver.support.wait import WebDriverWait as WD
from selenium.webdriver.support import expected_conditions as ec
from utils.Mouse_Actions.mouse_action import MouseActions


# pages/base_page.py,页面对象模型基础类，属于父类，这里设置页面操作组件，后面子类可以直接继承使用
class BasePage:
    def __init__(self, driver, timeout=10):
        self.driver = driver
        self.timeout = timeout
        self.ELEMENT_LOCATOR_MAP = {"xpath": By.XPATH,
                                    "id": By.ID,
                                    "name": By.NAME,
                                    "css": By.CSS_SELECTOR,
                                    "class": By.CLASS_NAME}

    # def find_element1(self, by, locator, model):
    #     return WebDriverWait(self.driver, self.timeout).until(
    #         EC.presence_of_element_located((by,locator))
    #     )

    # 元素定位
    def find_element(self, by, locator, model):  # 这里model可以理解为元素的名字，方便在日志中打印
        try:
            element = WebDriverWait(self.driver, self.timeout).until(
                # lambda x: x.find_element(self.ELEMENT_LOCATOR_MAP[by.lower()], locator)
                EC.presence_of_element_located((self.ELEMENT_LOCATOR_MAP[by.lower()],locator))
            )
        except TimeoutException as t:
            ERROR.logger.error(f'查找"{model}"元素失败,定位方式:{locator}')
            print('error: found "{}" timeout!'.format(locator), t)
        else:
            return element

    # 判断元素是否存在
    def is_element_exist(self, by, locator, model=None):
        INFO.logger.info(f'断言"{model}"元素存在，元素定位:{locator}')
        if by.lower() in self.ELEMENT_LOCATOR_MAP:
            try:
                WD(self.driver, self.timeout). \
                    until(ec.visibility_of_element_located((self.ELEMENT_LOCATOR_MAP[by], locator)))
            except TimeoutException:
                ERROR.logger.error(f'断言"{model}"元素不存在,定位方式:{locator}')
                # 截图
                return False
            return True
        else:
            print('the "{}" error!'.format(by))

    # 等待alert出现然后切换
    def switch_to_alert(self):
        """
        assert alert if exsit
        :return: alert obj
        """
        try:
            re = WD(self.driver, self.timeout).until(ec.alert_is_present())
        except (TimeoutException, NoAlertPresentException):
            print("error:no found alert")
        else:
            return self.driver.switch_to.alert

    # 获取alert 的提示信息
    def get_alert_text(self, model=None):
        """获取alert的提示信息"""
        INFO.logger.info(f"获取{model}的弹窗提示信息")
        alert = self.switch_to_alert()
        if alert:
            return alert.text
        else:
            return None

    # 弹窗确认
    def alert_accept(self):
        """
        alert 确认
        :return:
        """
        INFO.logger.info('点击弹窗确认按钮成功')
        self.switch_to_alert().accept()

    def click(self, by,locator,model):
        try:
            element = self.find_element(by, locator,model)
            element.click()
        except Exception as a:
            print(a)

    # 切换iframe
    def switch_to_frame(self, by, locator, model):
        """判断frame是否存在，存在就跳到iframe,有显示等待"""

        if by.lower() in self.ELEMENT_LOCATOR_MAP:
            try:
                WD(self.driver, self.timeout). \
                    until(ec.frame_to_be_available_and_switch_to_it((self.ELEMENT_LOCATOR_MAP[by], locator)))
                # time.sleep(0.5)
                INFO.logger.info(f'{model}iframe切换成功')
            except TimeoutException:
                ERROR.logger.error(f'{model}iframe 切换失败!!!')
                # 截图

        else:
            print('the "{}" error!'.format(by))

    def switch_to_default_frame(self):
        """返回默认的frame"""
        INFO.logger.info('切换到默认页面')
        try:
            self.driver.switch_to.default_content()
            INFO.logger.info('返回默认frame成功')
        except InvalidSwitchToTargetException:
            ERROR.logger.error('返回默认窗口失败!!!')

    #鼠标滚动到元素位置
    def mouse_click(self,by1,locator1,by,locator,model):
        try:
            # 2. 使用 ActionChains 执行悬停动作
            hover_element = self.driver.find_element(by1,locator1)
            actions1 = ActionChains(self.driver)
            actions1.move_to_element(hover_element).perform()
            # 循环滚动直到加载完成
            for _ in range(5):  # 滚动 5 次
                actions1.scroll_by_amount(0, 500).perform()
                time.sleep(1)  # 等待内容加载
            # 操作目标元素
            element = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((by, locator))
            )
            element.click()
        except TimeoutException as t:
            ERROR.logger.error(f'查找"{model}"元素失败,定位方式:{by}')
            print('error: found "{}" timeout!'.format(by), t)
        else:
            return element

    # 输入内容test
    # def send_keys(self, by, text):
    #     element = self.find_element(by)
    #     element.clear()
    #     element.send_keys(text)

    def send_keys(self, by, locator, value, model):
        """写数据"""
        INFO.logger.info(f'在"{model}"输入"{value}",元素定位:{locator}')
        try:
            element = self.find_element(by, locator,model)
            element.send_keys(value)
            return element
        except AttributeError:
            ERROR.logger.error(f'"{model}"输入操作失败!')

    # 获取title
    def get_title(self):
        return self.driver.title

    #上传文件
    def upload_file(self,by,locator,path,model):
        try:
            path = os.path.abspath(path)
            file_input = self.driver.find_element(by,locator)
            file_input.send_keys(path)
            print(f"文件上传成功: {path}")

        except Exception as e:
            print(f"文件上传失败: {e}")
            raise

    def mouse_hover(self,by,locator,model):
        #鼠标悬停
        try:
            # 2. 使用 ActionChains 执行悬停动作
            hover_element = self.driver.find_element(by, locator)
            actions1 = ActionChains(self.driver)
            actions1.move_to_element(hover_element).perform()
        except Exception as e:
            print(f"鼠标悬停失败！{model}")





